package com.wty.shop.controller.common.interceptor;

import avro.shaded.com.google.common.collect.Maps;
import com.wty.shop.common.Const;
import com.wty.shop.common.ServerResponse;
import com.wty.shop.pojo.User;
import com.wty.shop.util.CookieUtil;
import com.wty.shop.util.JsonUtil;
import com.wty.shop.util.RedisShardedPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author wangtengyu
 * @Create 2018-02-01-16:51
 */
@Slf4j
public class AuthorityInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("preHandle");
        //获取handlerMethod用于获取方法名与类名信息
        HandlerMethod handlerMethod=(HandlerMethod) handler;

        //获取访问来的方法名和类名
        String methodName=handlerMethod.getMethod().getName();
        String className= handlerMethod.getBean().getClass().getSimpleName();

        //解析参数，具体的key与value是什么，并打印日志
        StringBuffer requestParamBuffer=new StringBuffer();
        Map paramMap=request.getParameterMap();
        Iterator iterator=paramMap.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry entry=(Map.Entry)iterator.next();

            String mapKey=(String)entry.getKey();
            String mapValue= StringUtils.EMPTY;
            Object obj=entry.getValue();
            if(obj instanceof String[]){
                String[] strs=(String[])obj;
                mapValue= Arrays.toString(strs);
            }
            requestParamBuffer.append(mapKey).append("=").append(mapValue);
        }
/*       都是遍历取到key value的第二种方式
        Set keySet=paramMap.keySet();
        Iterator iterator=keySet.iterator();
        while(iterator.hasNext()){
            String mapKey=(String)iterator.next();
            String mapValue=(String)paramMap.get(mapKey);
        }*/
        if(StringUtils.equals(className,"UserManageController")&&StringUtils.equals(methodName,"login")){
            //对UserManageController不进行拦截，打印的时候不打印参数，因为有用户名密码等信息，防止日志泄露。
            log.info("权限拦截器拦截到请求 className{},methodName{}",className,methodName);
            return true;
        }

        //打印请求
        log.info("权限拦截器拦截到请求 className{},methodName{},params{}",className,methodName,requestParamBuffer);

        User user=null;
        String loginToken= CookieUtil.readLoginToken(request);
        if(StringUtils.isNotEmpty(loginToken)){
            String userJson=RedisShardedPoolUtil.get(loginToken);
            user= JsonUtil.String2Obj(userJson,User.class);
        }

        if(user==null ||user.getRole()!= Const.Role.ROLE_ADMIN){
            //用户未登录或者用户不是管理员
            //重置一个response
            response.reset();//这里要添加reset，否则报异常 getWriter() has already been called for this response.
            response.setCharacterEncoding("UTF-8");//设置编码，否则会乱码
            response.setContentType("application/json;charset=UTF-8");//这里要设置返回值的类型，因为全部是json接口。
            PrintWriter out=response.getWriter();

            //再判断是用户为空还是用户没有权限 富文本的返回值和正常的不一样 再做一层特殊处理
            if(user==null){
                if(StringUtils.equals(className,"ProductManageController")&&StringUtils.equals(methodName,"richtextImgUpload")){
                    Map resultMap= Maps.newHashMap();
                    resultMap.put("success",false);
                    resultMap.put("msg","请登录管理员账号");
                    out.print(JsonUtil.obj2String(resultMap));
                }else {
                    out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截，用户未登录")));
                }
            }else{
                if(StringUtils.equals(className,"ProductManageController")&&StringUtils.equals(methodName,"richtextImgUpload")){
                    Map resultMap= Maps.newHashMap();
                    resultMap.put("success",false);
                    resultMap.put("msg","无权限进行当前操作");
                    out.print(JsonUtil.obj2String(resultMap));
                }else {
                    out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截，用户无权限操作")));
                }
            }
            //刷新流的缓存与关闭流
            out.flush();
            out.close();
            return false;
        }



        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion");
    }
}
